/**
 * Copyright: Copyright (c) 2018
 * Company:
 *
 * @author XueWei
 * @date 2018年9月5日 下午2:09:59
 * @version V1.0
 */
package com.smartcommunity.service.dataImport;

import cn.hutool.core.util.StrUtil;
import com.smartcommunity.base.bean.ExceptionCode;
import com.smartcommunity.base.common.CacheMap;
import com.smartcommunity.base.common.DataImport;
import com.smartcommunity.bean.constant.Constant;
import com.smartcommunity.bean.entity.ImportErrorMsg;
import com.smartcommunity.bean.entity.ImportField;
import com.smartcommunity.controller.DataImportBase;
import com.smartcommunity.dao.village.RealCompanyDao;
import com.smartcommunity.entity.village.RealCompany;
import com.smartcommunity.entity.village.RealCompanyPeople;
import com.smartcommunity.exception.BusinessException;
import com.smartcommunity.log.interceptor.Log;
import com.smartcommunity.service.dataImport.model.RealCompanyPeopleExportModel;
import com.smartcommunity.utils.IDCardUtil;
import com.smartcommunity.utils.RegExUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

import static org.apache.commons.lang3.StringUtils.*;

/**
 * @ClassName: RealCompanyPeopleImport
 * @Description: 实有单位从业人员信息导入
 * @author XueWei
 * @date 2018年9月5日 下午2:09:59
 *
 */
@Component("realCompanyPeople")
@Slf4j
public class RealCompanyPeopleImport  extends DataImportBase implements DataImport {

    @Autowired
    private RealCompanyDao realCompanyDao;

    /**
     * 模板类型
     */
    private String type = "从业人员";

    /**
     * 内容标题
     */
    private  String[] headerTitle = new String[]{"姓名","证件类型","证件号码","性别","户籍地址","居住地址","电话号码"};

    /**
     * 错误信息
     */
    private  String[] headerErrorMsg = new String[]{"为空、或长度超过100位","为空、或类型错误","长度超过18位","","长度超过64位","长度超过64位","格式错误"};

    /**
     * key taskId,value progress
     */
    final int cacheSize = 100000;
    Map<String, Integer> progressTag = new LinkedHashMap<String, Integer>((int) Math.ceil(cacheSize / 0.75f) + 1, 0.75f, true) {
        @Override
        protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
            return size() > cacheSize;
        }
    };

    @Override
    @Log(info = "从业人员模板导入")
    public String importData(List list, String villageCode,String fileName, String taskId,HttpServletResponse response) {
        progressTag.put(taskId, 10);
        //小区编号（必填）
        if (StringUtils.isBlank(villageCode)) {
            throw new IllegalArgumentException("公司编号不为空！");
        }
        //初始化导入模板信息
        ImportErrorMsg msg = getFiledInfo(type,headerTitle,headerErrorMsg);
        //字段校验信息
        List<ImportField> fieldList = msg.getFieldList();

        // 根据小区编码（单位ID）获取单位信息
        RealCompany company  =  realCompanyDao.getRealCompany(villageCode);

        List<Object[]> objList = (List<Object[]>) list;
        //存储错误信息
        List<RealCompanyPeopleExportModel> dataListCopy = new ArrayList<>();
        List<RealCompanyPeople> peopleList = new ArrayList<>();
        RealCompanyPeople realCompanyPeople;
        int size = objList.size();
        int errorCount = 0;
        List<String> ids = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            boolean isError = false;
            int currentRow = Constant.START_ROW + i;
            Object[] objects = objList.get(i);

            int fixColumnLen = 8;
            if(objects.length < fixColumnLen){
                throw new BusinessException("模板文件列数不对，请检查模板文件！");
            }

            // 空行校验，跳过空行
            List<String> oneLine = Arrays.stream(objects)
                    .map(o -> StrUtil.trim(Objects.toString(o, EMPTY)))
                    .collect(Collectors.toList());
            if(oneLine.stream().allMatch(StrUtil::isEmpty)){
                log.info("第{}行全为空，跳过该行",currentRow);
                continue;
            }

            realCompanyPeople = new RealCompanyPeople();
            realCompanyPeople.setVillageCode(company.getVillageCode());

            StringBuffer errorMessages = new StringBuffer();

            //根据单位名称获取单位ID
            realCompanyPeople.setCompanyId(company.getCompanyId());

            // 人员姓名(必填)
            String name = "null".equals(String.valueOf(objects[0])) ? "" : String.valueOf(objects[0]);
            if (StringUtils.isBlank(name) || length(name) >100 ) {
                String errorMsg = appendErrorMsg(fieldList.get(0).getTitle(), name, fieldList.get(0).getErrorMsg());
                errorMessages.append(errorMsg);
                isError = true;
            }else{
                realCompanyPeople.setName(name);
            }

            // 设置证件类型（非必填）
            String credentialType = String.valueOf(objects[1]);
            if(StringUtils.isNotBlank(credentialType)){
                if (CacheMap.CREDENTIAL_TYPE_NAME_MAP.get(credentialType)==null) {
                    //添加错误的行数
                    String errorMsg = appendErrorMsg(fieldList.get(1).getTitle(), credentialType, fieldList.get(1).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }else{
                    realCompanyPeople.setCredentialType(String.valueOf(CacheMap.CREDENTIAL_TYPE_NAME_MAP.get(credentialType)));
                    realCompanyPeople.setCredentialTypeCN(credentialType);
                }
            }

            // 证件号码(非必填)
            String credentialNo = "null".equals(String.valueOf(objects[2])) ? "" : String.valueOf(objects[2]);
            realCompanyPeople.setCredentialNo("");
            if (StringUtils.isNotBlank(credentialNo) ) {
                if(length(credentialNo)>18){
                    String errorMsg = appendErrorMsg(fieldList.get(2).getTitle(), credentialNo, fieldList.get(2).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realCompanyPeople.setCredentialNo(credentialNo);
            }

            // 人员性别(非必填)
            String sex = "null".equals(String.valueOf(objects[3])) ? "" : String.valueOf(objects[3]);
            if (StringUtils.isNotBlank(sex)) {
                if(!CacheMap.GENDER_NAME_MAP.containsKey(sex)){
                    String errorMsg = appendErrorMsg(fieldList.get(3).getTitle(), sex, fieldList.get(4).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }else {
                    realCompanyPeople.setSex(CacheMap.GENDER_NAME_MAP.get(sex)==null?"":CacheMap.GENDER_NAME_MAP.get(sex).toString());
                }
            }else{
                //判断证件号码是否为身份证
                realCompanyPeople.setSex("未知");
                if (RegExUtils.isIdCardNo(credentialNo)) {
                    Integer genderInfo = IDCardUtil.getSex(credentialNo);
                    if(genderInfo!=null){
                        sex = genderInfo==0?"女":"男";
                        realCompanyPeople.setSex(sex);
                    }
                }
            }

            // 户籍地(非必填)
            String bornAddress = "null".equals(String.valueOf(objects[4])) ? "" : String.valueOf(objects[4]);
            if (!"".equals(bornAddress)) {
                if(length(bornAddress)>64){
                    String errorMsg = appendErrorMsg(fieldList.get(4).getTitle(), bornAddress, fieldList.get(4).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realCompanyPeople.setBornAddress(bornAddress);
            }
            // 居住地(非必填)
            String liveAddress = "null".equals(String.valueOf(objects[5])) ? "" : String.valueOf(objects[5]);
            if(!"".equals(liveAddress)) {
                if(length(liveAddress)>64){
                    String errorMsg = appendErrorMsg(fieldList.get(5).getTitle(), liveAddress, fieldList.get(5).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realCompanyPeople.setLiveAddress(liveAddress);
            }
            // 联系方式(非必填)
            String phone = "null".equals(String.valueOf(objects[6])) ? "" : String.valueOf(objects[6]);
            if(!"".equals(phone)) {
                if(length(phone)>20 || !RegExUtils.isNumeric(phone)){
                    String errorMsg = appendErrorMsg(fieldList.get(6).getTitle(), phone, fieldList.get(6).getErrorMsg());
                    errorMessages.append(errorMsg);
                    isError = true;
                }
                realCompanyPeople.setPhone(phone);
            }

            //判断当前行是否有错误
            if (isError) {
                errorCount++;
                RealCompanyPeopleExportModel exportModel = new RealCompanyPeopleExportModel();
                exportModel.setName(name);
                exportModel.setCredentialNo(credentialNo);
                exportModel.setCredentialType(credentialType);
                exportModel.setSex(sex);
                exportModel.setBornAddress(bornAddress);
                exportModel.setLiveAddress(liveAddress);
                exportModel.setPhone(phone);
                exportModel.setErrorMsg(errorMessages.toString());
                dataListCopy.add(exportModel);
            } else {
                ids.add(realCompanyPeople.getCredentialNo());
                peopleList.add(realCompanyPeople);
            }
        }

        try {
            progressTag.put(taskId, 20);
            if(!peopleList.isEmpty()){
                //删除已存在证件号的数据
                realCompanyDao.deleteRealCompanyPeopleByNo(ids);
                realCompanyDao.addRealCompanyPeopleByList(peopleList);
            }
            //正常的数据需要导入进去，错误的数据返回到Excel
            if (errorCount>0) {
                String errorFileName = exportExcelToLocal(taskId,fileName,headerTitle,dataListCopy);
                progressTag.put(taskId,100);
                return errorFileName;
            }
        } catch (Exception e) {
            log.error("导入实有单位从业人员错误,保存数据库异常！",e);
            throw new BusinessException(ExceptionCode.COMPANY_SQL_EXCEPTION_CODE,"实有单位从业人员导入失败,保存数据库异常！");
        }
        log.info("实有单位从业人员导入完成");
        progressTag.put(taskId, 100);
        return "";
    }

    @Override
    public int getImportDataProgress(String taskId) {
        return progressTag.get(taskId) == null ? 0 : progressTag.get(taskId);
    }

}
